﻿using System;
using System.Collections.Generic;
using System.Linq;
using ServiceStack.Redis;

namespace Redis.Core
{
    /// <summary>
    /// Redis 管理器
    /// </summary>
    public class Manager:IDisposable    
    {
        public PooledRedisClientManager ClientManager;

        public RedisClientManagerConfig RedisConfig { get; internal set; }

        public static Manager Default { get; internal set; }

        public Dictionary<String, String> Password = new Dictionary<String, String>();

        public Manager(RedisConfig config)
        {
            RedisConfig = new RedisClientManagerConfig
            {
                // “写”链接池链接数 
                MaxWritePoolSize = config.MaxWritePoolSize,
                // “读”链接池链接数 
                MaxReadPoolSize = config.MaxReadPoolSize,
                //自动启动
                AutoStart = true,
            };
            var ReadWrite = config.ReadWirteHost.Select(s => s.ConnectionString).ToList();
            var ReadOnlyHosts = config.ReadOnlyHosts.Select(s => s.ConnectionString).ToList();

            foreach (var item in config.ReadWirteHost)
            {
                Password[item.ConnectionString] = item.Password;
            }

            foreach (var item in config.ReadOnlyHosts)
            {
                Password[item.ConnectionString] = item.Password;
            }

            ClientManager = new PooledRedisClientManager(ReadWrite, ReadOnlyHosts, RedisConfig);
        }

        public static Manager Create(RedisConfig config)
        {
            return new Manager(config);
        }

        public static void Init(RedisConfig config)
        {
            Default = new Manager(config);
            if (!Default.TestConnection(out Exception ex))
            {
                throw ex;
            }
        }

        public void Save()
        {
            using (var  c = GetClient())
            {
                c.Save();
            }
        }
        public void SaveAsync()
        {
            using (var c = GetClient())
            {
                c.SaveAsync();
            }
        }



        public void UnWatch()
        {
            using (var c = GetClient())
            {
                c.UnWatch();
            }
        }
        public void Watch(params string[] keys)
        {
            using (var c = GetClient())
            {
                c.Watch(keys);
            }
        }

        public Boolean TestConnection(out Exception ex)
        {
            try
            {
                ex = null;
                using (var c = GetClient())
                {
                    var sr = c.LastSave;
                    return true;
                }
            }
            catch (Exception exc)
            {
                ex = exc;
                return false;
            }
        }





        /// <summary>
        /// 客户端缓存操作对象
        /// </summary>
        public IRedisClient GetClient()
        {
            if (ClientManager != null)
            {
                var client = ClientManager.GetClient();
                client.Password = Password[String.Format("{0}:{1}", client.Host, client.Port)];
                return client;
            }
            return null;
        }

        public void Dispose()
        {
            if (ClientManager != null)
            {
                ClientManager.Dispose();
                ClientManager = null;
            }
        }
    }
}
